/**
  ETFAna project, Anyang Normal University && IMP-CAS
  \class ETFAmpCh
  \brief abstract base class for a general raw data channel
  \author SUN Yazhou, asia.rabbit@163.com
  \since 2021-09-27
  \date 2023-10-27 last modified
  \attention
  changelog
  <table>
  <tr>  <th>Date        <th>Author      <th>Description                    </tr>
  <tr>  <td>2021-09-27   <td>Asia Sun    <td>file created                   </tr>
  </table>

  \copyright Copyright (c) 2021-2024 Anyang Normal U. && IMP-CAS with LGPLv3 LICENSE
*/

#include <iostream>
#include <algorithm>
#include "ETFAmpCh.h"
#include "ETFMsg.h"

using std::cout;
using std::endl;
using std::swap;

ETFAmpCh::ETFAmpCh() : ETFRawChannel(){
  Initialize();
} // end ctor

ETFAmpCh::ETFAmpCh(const ETFAmpCh &c) : ETFRawChannel(c), va(c.va),
fOverflow(c.fOverflow), fUnderflow(c.fUnderflow), fRange(c.fRange){
  fIsT = false;
} // end ctor

ETFAmpCh::~ETFAmpCh(){}

double ETFAmpCh::GetAmplitude(int i) const{
  if(i < 0 || i >= int(va.size())){
    // ETFMsg::Error("ETFAmpCh", "Requested subscipt %d out of bounds", i);
    return -999.;
  } // end if
  return va[i];
} // end member function GetAmplitude

void ETFAmpCh::SetAmplitude(double amp, int i){
  if(int(va.size()) <= i) va.resize(i + 1);
  va[i] = amp;
} // end member function SetAmplitude

void ETFAmpCh::AddAmplitude(double amp){
  va.push_back(amp);
} // end member function AddAmplitude

void ETFAmpCh::Reset(){
  // ETFRawChannel::Reset();
  va.clear();
  // fOverflow = true; fUnderflow = true;
  // fRange = false;
} // end member function Reset

void ETFAmpCh::Print(const char *) const{
  cout << "Amp, ChID: \033[34;1m" << fChannelId << "\n\033[0m";
  int i = 0;
  cout << "Overflow: " << std::boolalpha << fOverflow << "  ";
  cout << "UnderFlow: " << fUnderflow << std::noboolalpha << "  ";
  cout << "Range: " << (fRange ? "High" : "Low") << endl;
  cout << "good() " << (good() ? "\033[32;1m:)" : "\033[31;1m:(") << "\033[0m" << endl;
  for(const auto &v : va) cout << i++ << ": \t" << v << endl;
} // end member function Print

// rg: range, -1: solo range; 0: high range; 1: low range
void ETFAmpCh::SetAmplitude(double amp, int rg, bool ov, bool un){
  if(-1 == rg || 0 == nv()){ // single range, or the first value of dual range
    fOverflow = ov; fUnderflow = un; fRange = rg;
    return AddAmplitude(amp);
  } // end if

  //-- dual range assignment, the second one --//
  SetAmplitude(amp, 1);
  // signal too high or too low - dump
  if((!fRange && fOverflow) || (fRange && fUnderflow)) return;
  if((!rg && ov) || (rg && un)) return;
  // at least one range is fit //
  const bool fit0 = !fOverflow && !fUnderflow, fit1 = !ov && !un;
  // both range are fit
  if(fit0 && fit1){
    if(rg) swap(va[0], va[1]); // 2nd is low range (more precise), move to 1st
    return;
  } // end if
  // only 1 range is fit
  if(fit1){ // push the 2nd to the 1st
    swap(va[0], va[1]);
    fOverflow = fUnderflow = false;
  } // end if
} // end member funtion SetAmplitude
